﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using DPFP;
using DPFP.Capture;
using DPFP.Error;
using DPFP.Gui;
using DPFP.Processing;
using DPFP.Verification;
using System.ComponentModel;
using System.Data;
using Properties;
using IngressApp.BC;
using System.Threading;
using System.IO;

namespace IngressApp.Terminal
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    /// 

    public delegate void MessageCtrl(object state);
    public partial class MainWindow : Window, DPFP.Capture.EventHandler
    {
        private DPFP.Capture.Capture Capturer;
        private DPFP.Verification.Verification Verificator;
        private DPFP.Template Template;
        Enrollment Enroller = new Enrollment();
        private DataTable EmpleadoHuella;
        private List<DataRow> EmpleadosHuellas;

        private System.Timers.Timer tempMessage;

        private void exMessageCtrl(object state)
        {

        }

        private int idEmp = 0;
        public int IdEmp
        {
            get { return idEmp; }
            set { idEmp = value; }
        }

        public MainWindow()
        {

            InitializeComponent();

            Init();
        }



        #region Event handlers

        public void OnComplete(object Capture, string ReaderSerialNumber, Sample Sample)
        {

            Process(Sample);
        }

        public void OnFingerGone(object Capture, string ReaderSerialNumber)
        {

        }

        public void OnFingerTouch(object Capture, string ReaderSerialNumber)
        {

        }

        public void OnReaderConnect(object Capture, string ReaderSerialNumber)
        {

            Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => lblDevice.Content = "Ingresa tu Huella"), null);

        }

        public void OnReaderDisconnect(object Capture, string ReaderSerialNumber)
        {
            Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => lblDevice.Content = "Lector desconectado"), null);

        }

        public void OnSampleQuality(object Capture, string ReaderSerialNumber, CaptureFeedback CaptureFeedback)
        {

        }
        #endregion

        public void Init()
        {
            Template = new DPFP.Template();
            Verificator = new DPFP.Verification.Verification();
            UpdateStatus();
            tempMessage = new System.Timers.Timer(5000);
            tempMessage.Elapsed += new System.Timers.ElapsedEventHandler(tempMessage_Elapsed);
            try
            {
                Capturer = new DPFP.Capture.Capture();				// Create a capture operation.

                if (null != Capturer)
                    Capturer.EventHandler = this;					// Subscribe for capturing events.
                else
                    MessageBox.Show("Can't initiate capture operation!");
            }
            catch
            {
                MessageBox.Show("Can't initiate capture operation!");
            }

            GenDataTable();

            Start();

        }

        void tempMessage_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => lblMensaje.Content = ""), null);

            tempMessage.Stop();
        }

        private void GenDataTable()
        {
            BCRead Read = new BCRead();
            EmpleadoHuella = Read.readEmpleadosHuellas();

            EmpleadosHuellas = EmpleadoHuella.AsEnumerable().ToList();

        }

        protected void Start()
        {
            if (null != Capturer)
            {
                try
                {

                    Capturer.StartCapture();
                    //MessageBox.Show("Using the fingerprint reader, scan your fingerprint.");
                }
                catch
                {
                    //MessageBox.Show("Can't initiate capture!");
                }
            }
        }

        protected void Stop()
        {
            if (null != Capturer)
            {
                try
                {
                    Capturer.StopCapture();
                }
                catch
                {
                    MessageBox.Show("Can't terminate capture!");
                }
            }
        }

        protected DPFP.FeatureSet ExtractFeatures(DPFP.Sample Sample, DPFP.Processing.DataPurpose Purpose)
        {
            DPFP.Processing.FeatureExtraction Extractor = new DPFP.Processing.FeatureExtraction();	// Create a feature extractor
            DPFP.Capture.CaptureFeedback feedback = DPFP.Capture.CaptureFeedback.None;
            DPFP.FeatureSet features = new DPFP.FeatureSet();
            Extractor.CreateFeatureSet(Sample, Purpose, ref feedback, ref features);			// TODO: return features as a result?
            if (feedback == DPFP.Capture.CaptureFeedback.Good)
                return features;
            else
                return null;
        }


        protected void Process(DPFP.Sample Sample)
        {
            int x = 0;
            bool Verified = false;
            //BCRead Read = new BCRead();

            foreach (DataRow row in EmpleadoHuella.Rows)
            {
                byte[] fpByte = new byte[1632];

                fpByte = Convert.FromBase64String(EmpleadoHuella.Rows[x].ItemArray[3].ToString());
                x++;
                DPFP.Template temp = new DPFP.Template();
                temp.DeSerialize(fpByte);

                DPFP.FeatureSet features = ExtractFeatures(Sample, DPFP.Processing.DataPurpose.Verification);

                // Check quality of the sample and start verification if it's good
                // TODO: move to a separate task
                if (features != null)
                {
                    // Compare the feature set with our template
                    DPFP.Verification.Verification.Result result = new DPFP.Verification.Verification.Result();
                    Verificator.Verify(features, temp, ref result);
                    //result.FARAchieved;
                    if (result.Verified) { Verified = true; break; }
                    else Verified = false;
                }

            }
            if (Verified)
            {
                BCRead read = new BCRead();
                DataTable resEmpleado = new DataTable();
                int idEmp = Convert.ToInt32(EmpleadoHuella.Rows[x - 1].ItemArray[1]);
                resEmpleado = read.readEmpleado(idEmp);
                BCUpdate updEmp = new BCUpdate();
                Empleado emp = new Empleado();

                emp.ApellidoMaterno = resEmpleado.Rows[0].ItemArray[3].ToString();
                emp.ApellidoPaterno = resEmpleado.Rows[0].ItemArray[2].ToString();
                emp.Estado = !(Convert.ToBoolean(resEmpleado.Rows[0].ItemArray[4]));
                emp.Nombres = resEmpleado.Rows[0].ItemArray[1].ToString();
                updEmp.update(emp, idEmp);

                Registro regEmpleado = new Registro();
                regEmpleado.Estado = !(Convert.ToBoolean(resEmpleado.Rows[0].ItemArray[4]));
                regEmpleado.Fecha = DateTime.Now;
                regEmpleado.IdEmpleado = idEmp;

                Application.Current.Dispatcher.BeginInvoke(
                    new ThreadStart(() => lblMensaje.Content = "Bienvenido " + emp.Nombres + " "
                                                                          + emp.ApellidoPaterno), null);


                BCInsert insert = new BCInsert();
                insert.insert(regEmpleado);
            }


            else
            {
                Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => lblMensaje.Content = "No se tiene registrada su huella"), null);
            }


            tempMessage.Start();
        }

        private void UpdateStatus()
        {

        }

        private void btnSalvar_Click(object sender, RoutedEventArgs e)
        {

            EmpleadoHuella obj = new EmpleadoHuella();
            obj.IdEmpleado = idEmp;
            obj.TipoHuella = 2;
            //obj.Huella = fpRes;

            BCUpdate insEmpleadoHuella = new BCUpdate();
            MessageBox.Show(insEmpleadoHuella.update(obj, idEmp));
            this.Close();
        }

    }
}
